<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>cmt.rig.spaceswitch &#8212; cmt  documentation</title>
    <link rel="stylesheet" href="../../../_static/bootstrap-sphinx.css" type="text/css" />
    <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
    <script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
    <script src="../../../_static/jquery.js"></script>
    <script src="../../../_static/underscore.js"></script>
    <script src="../../../_static/doctools.js"></script>
    <script src="../../../_static/language_data.js"></script>
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" />
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1'>
<meta name="apple-mobile-web-app-capable" content="yes">
<script type="text/javascript" src="../../../_static/js/jquery-1.11.0.min.js "></script>
<script type="text/javascript" src="../../../_static/js/jquery-fix.js "></script>
<script type="text/javascript" src="../../../_static/bootstrap-3.3.7/js/bootstrap.min.js "></script>
<script type="text/javascript" src="../../../_static/bootstrap-sphinx.js "></script>

  </head><body>

  <div id="navbar" class="navbar navbar-default navbar-fixed-top">
    <div class="container">
      <div class="navbar-header">
        <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="../../../index.html">
          cmt</a>
        <span class="navbar-text navbar-version pull-left"><b></b></span>
      </div>

        <div class="collapse navbar-collapse nav-collapse">
          <ul class="nav navbar-nav">
            
            
              <li class="dropdown globaltoc-container">
  <a role="button"
     id="dLabelGlobalToc"
     data-toggle="dropdown"
     data-target="#"
     href="../../../index.html">Site <b class="caret"></b></a>
  <ul class="dropdown-menu globaltoc"
      role="menu"
      aria-labelledby="dLabelGlobalToc"><ul>
<li class="toctree-l1"><a class="reference internal" href="../../../installation.html">Installation Instructions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../rigging.html">Rigging Tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../dge.html">Dependency Graph Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../customwidgets.html">Custom Widgets</a></li>
</ul>
</ul>
</li>
              
                <li class="dropdown">
  <a role="button"
     id="dLabelLocalToc"
     data-toggle="dropdown"
     data-target="#"
     href="#">Page <b class="caret"></b></a>
  <ul class="dropdown-menu localtoc"
      role="menu"
      aria-labelledby="dLabelLocalToc"></ul>
</li>
              
            
            
              
                
              
            
            
            
            
              <li class="hidden-sm"></li>
            
          </ul>

          
            
<form class="navbar-form navbar-right" action="../../../search.html" method="get">
 <div class="form-group">
  <input type="text" name="q" class="form-control" placeholder="Search" />
 </div>
  <input type="hidden" name="check_keywords" value="yes" />
  <input type="hidden" name="area" value="default" />
</form>
          
        </div>
    </div>
  </div>

<div class="container">
  <div class="row">
    <div class="body col-md-12 content" role="main">
      
  <h1>Source code for cmt.rig.spaceswitch</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;Space switching without constraints or extra DAG nodes.</span>

<span class="sd">Contains functions to create a space switching network as well as seamlessly switching</span>
<span class="sd">between spaces.</span>

<span class="sd">Example Usage</span>
<span class="sd">=============</span>

<span class="sd">::</span>

<span class="sd">    import cmt.rig.spaceswitch as spaceswitch</span>

<span class="sd">    # Create the space switch</span>
<span class="sd">    spaceswitch.create_space_switch(</span>
<span class="sd">        pole_vector_control,</span>
<span class="sd">        [(ik_control, &quot;foot&quot;), (root_control, &quot;root&quot;), (world_control, &quot;world&quot;)],</span>
<span class="sd">        switch_attribute=&quot;space&quot;,</span>
<span class="sd">        use_rotate=False,</span>
<span class="sd">    )</span>

<span class="sd">    # Seamless switch</span>
<span class="sd">    spaceswitch.switch_space(pole_vector_control, &quot;space&quot;, 1, create_keys=False)</span>

<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">maya.cmds</span> <span class="k">as</span> <span class="nn">cmds</span>
<span class="kn">import</span> <span class="nn">maya.api.OpenMaya</span> <span class="k">as</span> <span class="nn">OpenMaya</span>
<span class="kn">from</span> <span class="nn">cmt.dge</span> <span class="kn">import</span> <span class="n">dge</span>


<div class="viewcode-block" id="create_space_switch"><a class="viewcode-back" href="../../../rig/spaceswitch.html#cmt.rig.spaceswitch.create_space_switch">[docs]</a><span class="k">def</span> <span class="nf">create_space_switch</span><span class="p">(</span>
    <span class="n">node</span><span class="p">,</span> <span class="n">drivers</span><span class="p">,</span> <span class="n">switch_attribute</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">use_translate</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">use_rotate</span><span class="o">=</span><span class="kc">True</span>
<span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Creates a space switch network.</span>

<span class="sd">    The network uses the offsetParentMatrix attribute and does not create any</span>
<span class="sd">    constraints or new dag nodes.</span>

<span class="sd">    :param node: Transform to drive</span>
<span class="sd">    :param drivers: List of tuples: [(driver1, &quot;spaceName1&quot;), (driver2, &quot;spaceName2&quot;)]</span>
<span class="sd">    :param switch_attribute: Name of the switch attribute to create on the target node.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">switch_attribute</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">switch_attribute</span> <span class="o">=</span> <span class="s2">&quot;space&quot;</span>

    <span class="k">if</span> <span class="n">cmds</span><span class="o">.</span><span class="n">objExists</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">switch_attribute</span><span class="p">)):</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">deleteAttr</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">at</span><span class="o">=</span><span class="n">switch_attribute</span><span class="p">)</span>
    <span class="n">names</span> <span class="o">=</span> <span class="p">[</span><span class="n">d</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">drivers</span><span class="p">]</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">addAttr</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">ln</span><span class="o">=</span><span class="n">switch_attribute</span><span class="p">,</span> <span class="n">at</span><span class="o">=</span><span class="s2">&quot;enum&quot;</span><span class="p">,</span> <span class="n">en</span><span class="o">=</span><span class="s2">&quot;:&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">names</span><span class="p">),</span> <span class="n">keyable</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>

    <span class="c1"># Create attribute to toggle translation in the matrices</span>
    <span class="n">enable_translate_attr</span> <span class="o">=</span> <span class="n">_create_bool_attribute</span><span class="p">(</span>
        <span class="n">node</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">UseTranslate&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">switch_attribute</span><span class="p">),</span> <span class="n">use_translate</span>
    <span class="p">)</span>

    <span class="c1"># Create attribute to toggle rotation in the matrices</span>
    <span class="n">enable_rotate_attr</span> <span class="o">=</span> <span class="n">_create_bool_attribute</span><span class="p">(</span>
        <span class="n">node</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">UseRotate&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">switch_attribute</span><span class="p">),</span> <span class="n">use_rotate</span>
    <span class="p">)</span>

    <span class="n">blend</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">createNode</span><span class="p">(</span><span class="s2">&quot;blendMatrix&quot;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">_spaceswitch&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">node</span><span class="p">))</span>

    <span class="c1"># Get the current offset parent matrix.  This is used as the starting blend point</span>
    <span class="n">m</span> <span class="o">=</span> <span class="n">OpenMaya</span><span class="o">.</span><span class="n">MMatrix</span><span class="p">(</span><span class="n">cmds</span><span class="o">.</span><span class="n">getAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.offsetParentMatrix&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">node</span><span class="p">)))</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">setAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.inputMatrix&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">blend</span><span class="p">),</span> <span class="nb">list</span><span class="p">(</span><span class="n">m</span><span class="p">),</span> <span class="nb">type</span><span class="o">=</span><span class="s2">&quot;matrix&quot;</span><span class="p">)</span>

    <span class="n">parent</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">listRelatives</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">parent</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
    <span class="n">to_parent_local</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.worldInverseMatrix[0]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">parent</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="k">if</span> <span class="n">parent</span> <span class="k">else</span> <span class="kc">None</span>

    <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">driver</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">drivers</span><span class="p">):</span>
        <span class="n">driver</span> <span class="o">=</span> <span class="n">driver</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>

        <span class="n">_connect_driver_matrix_network</span><span class="p">(</span><span class="n">blend</span><span class="p">,</span> <span class="n">node</span><span class="p">,</span> <span class="n">driver</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">to_parent_local</span><span class="p">)</span>

        <span class="n">target_attr</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.target[</span><span class="si">{}</span><span class="s2">]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">blend</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>

        <span class="c1"># Hook up the weight toggle when switching spaces</span>
        <span class="n">dge</span><span class="p">(</span>
            <span class="s2">&quot;x = switch == </span><span class="si">{}</span><span class="s2"> ? 1 : 0&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">i</span><span class="p">),</span>
            <span class="n">x</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.weight&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">target_attr</span><span class="p">),</span>
            <span class="n">switch</span><span class="o">=</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">switch_attribute</span><span class="p">),</span>
        <span class="p">)</span>

        <span class="c1"># Connect the translation, rotation toggles</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="n">enable_translate_attr</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.useTranslate&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">target_attr</span><span class="p">))</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="n">enable_rotate_attr</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.useRotate&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">target_attr</span><span class="p">,</span> <span class="n">i</span><span class="p">))</span>

    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span>
        <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.outputMatrix&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">blend</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.offsetParentMatrix&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
    <span class="p">)</span></div>


<span class="k">def</span> <span class="nf">_create_bool_attribute</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">attribute</span><span class="p">,</span> <span class="n">default_value</span><span class="p">):</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">addAttr</span><span class="p">(</span>
        <span class="n">node</span><span class="p">,</span> <span class="n">ln</span><span class="o">=</span><span class="n">attribute</span><span class="p">,</span> <span class="n">at</span><span class="o">=</span><span class="s2">&quot;bool&quot;</span><span class="p">,</span> <span class="n">defaultValue</span><span class="o">=</span><span class="n">default_value</span><span class="p">,</span> <span class="n">keyable</span><span class="o">=</span><span class="kc">True</span>
    <span class="p">)</span>
    <span class="k">return</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">attribute</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">_connect_driver_matrix_network</span><span class="p">(</span><span class="n">blend</span><span class="p">,</span> <span class="n">node</span><span class="p">,</span> <span class="n">driver</span><span class="p">,</span> <span class="n">index</span><span class="p">,</span> <span class="n">to_parent_local</span><span class="p">):</span>
    <span class="c1"># The multMatrix node will calculate the transformation to blend to when driven</span>
    <span class="c1"># by this driver transform: driverWorld * nodeOffsetToDriver * nodeParentInverse</span>
    <span class="n">mult</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">createNode</span><span class="p">(</span>
        <span class="s2">&quot;multMatrix&quot;</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s2">&quot;spaceswitch_</span><span class="si">{}</span><span class="s2">_to_</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">driver</span><span class="p">)</span>
    <span class="p">)</span>

    <span class="n">offset</span> <span class="o">=</span> <span class="p">(</span>
        <span class="n">OpenMaya</span><span class="o">.</span><span class="n">MMatrix</span><span class="p">(</span><span class="n">cmds</span><span class="o">.</span><span class="n">getAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.worldMatrix[0]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">node</span><span class="p">)))</span>
        <span class="o">*</span> <span class="n">OpenMaya</span><span class="o">.</span><span class="n">MMatrix</span><span class="p">(</span><span class="n">cmds</span><span class="o">.</span><span class="n">getAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.matrix&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">node</span><span class="p">)))</span><span class="o">.</span><span class="n">inverse</span><span class="p">()</span>
        <span class="o">*</span> <span class="n">OpenMaya</span><span class="o">.</span><span class="n">MMatrix</span><span class="p">(</span><span class="n">cmds</span><span class="o">.</span><span class="n">getAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.worldInverseMatrix[0]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">)))</span>
    <span class="p">)</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">setAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.matrixIn[0]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mult</span><span class="p">),</span> <span class="nb">list</span><span class="p">(</span><span class="n">offset</span><span class="p">),</span> <span class="nb">type</span><span class="o">=</span><span class="s2">&quot;matrix&quot;</span><span class="p">)</span>

    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.worldMatrix[0]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">driver</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.matrixIn[1]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mult</span><span class="p">))</span>

    <span class="k">if</span> <span class="n">to_parent_local</span><span class="p">:</span>
        <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span><span class="n">to_parent_local</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.matrixIn[2]&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mult</span><span class="p">))</span>

    <span class="n">cmds</span><span class="o">.</span><span class="n">connectAttr</span><span class="p">(</span>
        <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.matrixSum&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">mult</span><span class="p">),</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.target[</span><span class="si">{}</span><span class="s2">].targetMatrix&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">blend</span><span class="p">,</span> <span class="n">index</span><span class="p">)</span>
    <span class="p">)</span>


<div class="viewcode-block" id="switch_space"><a class="viewcode-back" href="../../../rig/spaceswitch.html#cmt.rig.spaceswitch.switch_space">[docs]</a><span class="k">def</span> <span class="nf">switch_space</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">attribute</span><span class="p">,</span> <span class="n">space</span><span class="p">,</span> <span class="n">create_keys</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Seamlessly switch between spaces</span>

<span class="sd">    :param node: Node to switch</span>
<span class="sd">    :param attribute: Space switching attribute on node</span>
<span class="sd">    :param space: Space index in the space attribute</span>
<span class="sd">    :param create_keys: True to create switching keys</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">m</span> <span class="o">=</span> <span class="n">cmds</span><span class="o">.</span><span class="n">xform</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">q</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">ws</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">m</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">setAttr</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">{}</span><span class="s2">.</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">attribute</span><span class="p">),</span> <span class="n">space</span><span class="p">)</span>
    <span class="n">cmds</span><span class="o">.</span><span class="n">xform</span><span class="p">(</span><span class="n">node</span><span class="p">,</span> <span class="n">ws</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">m</span><span class="o">=</span><span class="n">m</span><span class="p">)</span></div>
</pre></div>

    </div>
      
  </div>
</div>
<footer class="footer">
  <div class="container">
    <p class="pull-right">
      <a href="#">Back to top</a>
      
    </p>
    <p>
        &copy; Copyright 2018, Chad Vernon.<br/>
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.1.2.<br/>
    </p>
  </div>
</footer>
  </body>
</html>